/**
 * API客户端
 * 
 * 用途：负责将脑波数据通过HTTP POST请求发送到后端服务器
 * 方法：使用OkHttp库进行网络请求，Gson进行JSON序列化
 * 原理：将TabletBrainWaveData对象序列化为JSON格式，通过POST请求发送到指定的API端点
 */
package com.example.brain_wave.bluetooth.api

import com.example.brain_wave.bluetooth.model.TabletBrainWaveData
import com.example.brain_wave.api.model.TabletBrainWaveResponse
import com.google.gson.Gson
import kotlinx.coroutines.*
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import java.io.IOException
import com.example.brain_wave.config.AppConfig
import android.content.Context

class ApiClient(private val context: Context) {
    
    private val appConfig = AppConfig.getInstance(context)
    
    private val client = OkHttpClient.Builder()
        .connectTimeout(appConfig.connectTimeout.toLong(), java.util.concurrent.TimeUnit.SECONDS)
        .writeTimeout(appConfig.writeTimeout.toLong(), java.util.concurrent.TimeUnit.SECONDS)
        .readTimeout(appConfig.readTimeout.toLong(), java.util.concurrent.TimeUnit.SECONDS)
        .build()
    
    private val gson = Gson()
    private val mediaType = "application/json; charset=utf-8".toMediaType()
    
    // API端点URL
    private var baseUrl: String = ""
    private var endpoint: String = "/api/brainwave/data"
    
    // 请求结果回调
    private var onSuccess: ((String) -> Unit)? = null
    private var onError: ((String) -> Unit)? = null
    // 新增：服务端数据响应回调
    private var onServerDataReceived: ((TabletBrainWaveResponse) -> Unit)? = null
    
    /**
     * 设置API基础URL
     */
    fun setBaseUrl(url: String) {
        baseUrl = url.trimEnd('/')
    }
    
    /**
     * 设置API端点
     */
    fun setEndpoint(endpoint: String) {
        this.endpoint = endpoint
    }
    
    /**
     * 设置成功回调
     */
    fun setOnSuccess(callback: (String) -> Unit) {
        onSuccess = callback
    }
    
    /**
     * 设置错误回调
     */
    fun setOnError(callback: (String) -> Unit) {
        onError = callback
    }
    
    /**
     * 设置服务端数据响应回调
     */
    fun setOnServerDataReceived(callback: (TabletBrainWaveResponse) -> Unit) {
        onServerDataReceived = callback
    }
    
    /**
     * 发送脑波数据到服务器
     */
    fun sendBrainWaveData(data: TabletBrainWaveData) {
        CoroutineScope(Dispatchers.IO).launch {
            try {
                val json = gson.toJson(data)
                val requestBody = json.toRequestBody(mediaType)
                
                val request = Request.Builder()
                    .url("$baseUrl$endpoint")
                    .post(requestBody)
                    .addHeader("Content-Type", "application/json")
                    .build()
                
                client.newCall(request).enqueue(object : Callback {
                    override fun onFailure(call: Call, e: IOException) {
                        CoroutineScope(Dispatchers.Main).launch {
                            onError?.invoke("网络请求失败: ${e.message}")
                        }
                    }
                    
                    override fun onResponse(call: Call, response: Response) {
                        // 先在IO线程处理网络响应
                        CoroutineScope(Dispatchers.IO).launch {
                            try {
                                if (response.isSuccessful) {
                                    val responseBody = response.body?.string() ?: ""
                                    
                                    // 切换到主线程执行回调
                                    withContext(Dispatchers.Main) {
                                        onSuccess?.invoke(responseBody)
                                    }
                                    
                                    // 尝试解析服务端返回的数据
                                     try {
                                         val serverResponse = gson.fromJson(responseBody, TabletBrainWaveResponse::class.java)
                                         withContext(Dispatchers.Main) {
                                             onServerDataReceived?.invoke(serverResponse)
                                         }
                                     } catch (e: Exception) {
                                         // 如果解析失败，只记录错误但不影响主流程
                                         println("解析服务端响应数据失败: ${e.message}")
                                     }
                                } else {
                                    withContext(Dispatchers.Main) {
                                        onError?.invoke("服务器错误: ${response.code} ${response.message}")
                                    }
                                }
                            } catch (e: Exception) {
                                withContext(Dispatchers.Main) {
                                    onError?.invoke("处理响应失败: ${e.message}")
                                }
                            }
                        }
                    }
                })
                
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    onError?.invoke("数据序列化失败: ${e.message}")
                }
            }
        }
    }
    
    /**
     * 同步发送数据（用于测试）
     */
    suspend fun sendBrainWaveDataSync(data: TabletBrainWaveData): Result<String> = withContext(Dispatchers.IO) {
        try {
            val json = gson.toJson(data)
            val requestBody = json.toRequestBody(mediaType)
            
            val request = Request.Builder()
                .url("$baseUrl$endpoint")
                .post(requestBody)
                .addHeader("Content-Type", "application/json")
                .build()
            
            val response = client.newCall(request).execute()
            
            if (response.isSuccessful) {
                val responseBody = response.body?.string() ?: ""
                Result.success(responseBody)
            } else {
                Result.failure(Exception("服务器错误: ${response.code} ${response.message}"))
            }
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
    
    /**
     * 测试连接
     */
    suspend fun testConnection(): Boolean = withContext(Dispatchers.IO) {
        try {
            val request = Request.Builder()
                .url("$baseUrl/health")
                .get()
                .build()
            
            val response = client.newCall(request).execute()
            response.isSuccessful
        } catch (e: Exception) {
            false
        }
    }
}